package com.study.concurrent.C_ThreadSynchronizationHelperClass.e_SynchronizationOnCommonPoint;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * Created by 赵超 on 2017/3/25.
 * 查找类
 */
public class Searcher implements Runnable {
    private int firstRow; // 要查找的开始范围
    private int lastRow; // 要查找的结束范围
    private MatrixMock matrixMock; // 矩阵
    private Results results; // 结果
    private int number; // 要查找的数字
    private final CyclicBarrier cyclicBarrier;

    /**
     * @param firstRow      要查找的开始范围
     * @param lastRow       要查找的结束范围
     * @param matrixMock    矩阵
     * @param results       结果
     * @param number        要查找的数字
     * @param cyclicBarrier
     */
    public Searcher(int firstRow, int lastRow, MatrixMock matrixMock,
                    Results results, int number, CyclicBarrier cyclicBarrier) {
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.matrixMock = matrixMock;
        this.results = results;
        this.number = number;
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        int counter;
        System.out.printf("%s 查找从 %d 行到 %d 行的数据...\n",
                Thread.currentThread().getName(), firstRow, lastRow);
        for (int i = firstRow; i < lastRow; i++) {
            int[] row = matrixMock.getRow(i);
            counter = 0;
            for (int j = 0; j < row.length; j++) {
                if (row[j] == number) {
                    counter++;
                }
            }
            results.setData(i, counter);
            System.out.printf("%s 查找完毕，从 %d 行到 %d 行 中的第 %d 行，待查找数字出现了 %d 次...\n",
                    Thread.currentThread().getName(), firstRow, lastRow, i + 1, counter);
        }
        try {
            /**
             * 当进入的线程达到指定数量的时候，
             * 最后一个进入的线程调用await()方法时（注意该线程已经执行完成查找任务），
             * 会自动执行传入CyclicBarrier类构造器的Runnable参数
             */
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}
